<?php
/**
 * 开馆时间和时间段查询API
 * 专门用于小程序获取近7日开馆情况和可预约时间段
 */

// 数据库配置
$dbConfig = [
    'host' => 'localhost',
    'name' => 'nzy_congqian_cn', 
    'user' => 'nzy_congqian_cn',
    'pass' => 'FsnXrDfDhm4wFJSX',
    'charset' => 'utf8mb4'
];

// 设置响应头
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
// 统一时区，避免日期/星期计算受服务器默认时区影响
date_default_timezone_set('Asia/Shanghai');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit;
}

// 数据库连接
try {
    $dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['name']};charset={$dbConfig['charset']}";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    jsonResponse([
        'success' => false,
        'message' => '数据库连接失败: ' . $e->getMessage()
    ]);
}

// 响应函数
function jsonResponse($data) {
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function success($data = null, $message = '操作成功') {
    jsonResponse([
        'code' => 200,
        'success' => true,
        'message' => $message,
        'data' => $data,
        'timestamp' => time()
    ]);
}

function error($message = '操作失败', $code = 400) {
    jsonResponse([
        'code' => $code,
        'success' => false,
        'message' => $message,
        'data' => null,
        'timestamp' => time()
    ]);
}

/**
 * 获取近7日开馆情况和可预约时间段
 */
function get7DaysSchedule() {
    global $pdo;
    
    try {
        $result = [];
        // 真实今天，用于判断 is_past
        $now = date('Y-m-d');
        
        // 起始日期：默认今天，可通过 start_date 或 date 传入
        $startDate = $_GET['start_date'] ?? ($_GET['date'] ?? $now);
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $startDate)) {
            $startDate = $now; // 兜底
        }
        
        // 获取可预约天数配置
        $configStmt = $pdo->prepare("SELECT config_value FROM museum_config WHERE config_key = 'advance_booking_days'");
        $configStmt->execute();
        $config = $configStmt->fetch(PDO::FETCH_ASSOC);
        $configDays = max(1, (int)($config['config_value'] ?? 7));
        
        // 支持前端可选传 days，最大不超过配置
        $requestedDays = (int)($_GET['days'] ?? $configDays);
        $totalDays = max(1, min($requestedDays, $configDays));
        
        // 不能超过配置窗口（从“今天”起算的最大可预约日）
        $endLimitDate = date('Y-m-d', strtotime("+{$configDays} days", strtotime($now)));
        
        // 获取所有活跃的时间段
        $timeSlotsQuery = "SELECT * FROM museum_time_slots WHERE is_active = 1 ORDER BY sort_order, start_time";
        $timeSlots = $pdo->query($timeSlotsQuery)->fetchAll(PDO::FETCH_ASSOC);
        
        for ($i = 0; $i < $totalDays; $i++) {
            $date = date('Y-m-d', strtotime("+{$i} days", strtotime($startDate)));
            if ($date > $endLimitDate) {
                break; // 超出可预约窗口
            }
            $dayOfWeek = date('N', strtotime($date)); // 1=周一, 7=周日
            $dayName = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'][$dayOfWeek];
            
            // 获取该日开馆时间设置（museum_schedule 的 day_of_week 以周一=1, 周日=7 存储）
            $scheduleQuery = "SELECT * FROM museum_schedule WHERE day_of_week = ?";
            $scheduleStmt = $pdo->prepare($scheduleQuery);
            $scheduleStmt->execute([$dayOfWeek]);
            $schedule = $scheduleStmt->fetch(PDO::FETCH_ASSOC);
            
            $dayInfo = [
                'date' => $date,
                'day_of_week' => $dayOfWeek,
                'day_name' => $dayName,
                'is_open' => false,
                'open_time' => null,
                'close_time' => null,
                'max_visitors' => 0,
                'closure_reason' => null,
                'available_slots' => [],
                'is_past' => strtotime($date) < strtotime($now)
            ];
            
            // 检查是否有开馆时间设置
            if (!$schedule || !$schedule['is_open']) {
                $dayInfo['closure_reason'] = '休馆日';
                $result[] = $dayInfo;
                continue;
            }
            
            // 检查特殊闭馆设置
            $closureQuery = "SELECT * FROM museum_closure_dates 
                           WHERE is_active = 1 
                           AND (
                               (closure_type = 'once' AND closure_date = ?) OR
                               (closure_type = 'yearly' AND DATE_FORMAT(closure_date, '%m-%d') = DATE_FORMAT(?, '%m-%d')) OR
                               (closure_type = 'weekly' AND DAYOFWEEK(closure_date) = DAYOFWEEK(?))
                           )";
            $closureStmt = $pdo->prepare($closureQuery);
            $closureStmt->execute([$date, $date, $date]);
            $closure = $closureStmt->fetch(PDO::FETCH_ASSOC);
            
            if ($closure) {
                $dayInfo['closure_reason'] = $closure['reason'] ?: '临时闭馆';
                $result[] = $dayInfo;
                continue;
            }
            
            // 正常开馆，设置基本信息
            $dayInfo['is_open'] = true;
            $dayInfo['open_time'] = substr($schedule['open_time'], 0, 5);
            $dayInfo['close_time'] = substr($schedule['close_time'], 0, 5);
            $dayInfo['max_visitors'] = (int)$schedule['max_visitors'];
            
            // 计算各时间段的可用情况
            foreach ($timeSlots as $slot) {
                // 检查时间段是否在开馆时间内
                $slotStart = $slot['start_time'];
                $slotEnd = $slot['end_time'];
                $openTime = $schedule['open_time'];
                $closeTime = $schedule['close_time'];
                
                $isSlotValid = ($slotStart >= $openTime && $slotEnd <= $closeTime);
                
                if (!$isSlotValid) {
                    continue; // 跳过不在开馆时间内的时段
                }
                
                // 查询该日该时段的已预约数量
                $reservedQuery = "SELECT COALESCE(SUM(visitor_count), 0) as reserved_count 
                                FROM reservations 
                                WHERE visit_date = ? 
                                AND time_slot_id = ? 
                                AND status IN ('confirmed', 'checked_in')";
                $reservedStmt = $pdo->prepare($reservedQuery);
                $reservedStmt->execute([$date, $slot['id']]);
                $reservedData = $reservedStmt->fetch(PDO::FETCH_ASSOC);
                $reservedCount = (int)($reservedData['reserved_count'] ?? 0);
                
                $maxVisitors = (int)$slot['max_visitors'];
                $availableCount = $maxVisitors - $reservedCount;
                $availableCount = max(0, $availableCount); // 确保不为负数
                
                $slotInfo = [
                    'slot_id' => (int)$slot['id'],
                    'slot_name' => $slot['slot_name'],
                    'start_time' => substr($slot['start_time'], 0, 5),
                    'end_time' => substr($slot['end_time'], 0, 5),
                    'max_visitors' => $maxVisitors,
                    'reserved_count' => $reservedCount,
                    'available_count' => $availableCount,
                    'is_available' => $availableCount > 0 && !$dayInfo['is_past'],
                    'is_full' => $availableCount <= 0
                ];
                
                $dayInfo['available_slots'][] = $slotInfo;
            }
            
            $result[] = $dayInfo;
        }
        
        success([
            'schedule_list' => $result,
            'time_slots' => array_map(function($slot) {
                return [
                    'id' => (int)$slot['id'],
                    'name' => $slot['slot_name'],
                    'start_time' => substr($slot['start_time'], 0, 5),
                    'end_time' => substr($slot['end_time'], 0, 5),
                    'max_visitors' => (int)$slot['max_visitors']
                ];
            }, $timeSlots),
            'query_date' => $startDate,
            'total_days' => count($result)
        ], '获取成功');
        
    } catch (Exception $e) {
        error('获取开馆时间失败: ' . $e->getMessage(), 500);
    }
}

/**
 * 获取指定日期的详细时间段信息
 */
function getDateDetail() {
    global $pdo;
    
    $date = $_GET['date'] ?? '';
    if (!$date || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
        error('请提供有效的日期格式 (YYYY-MM-DD)');
    }
    
    try {
        $dayOfWeek = date('N', strtotime($date));
        
        // 获取开馆时间设置
        $scheduleQuery = "SELECT * FROM museum_schedule WHERE day_of_week = ?";
        $scheduleStmt = $pdo->prepare($scheduleQuery);
        $scheduleStmt->execute([$dayOfWeek]);
        $schedule = $scheduleStmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$schedule || !$schedule['is_open']) {
            error('该日期为休馆日');
        }
        
        // 检查特殊闭馆
        $closureQuery = "SELECT * FROM museum_closure_dates 
                       WHERE is_active = 1 
                       AND (
                           (closure_type = 'once' AND closure_date = ?) OR
                           (closure_type = 'yearly' AND DATE_FORMAT(closure_date, '%m-%d') = DATE_FORMAT(?, '%m-%d')) OR
                           (closure_type = 'weekly' AND DAYOFWEEK(closure_date) = DAYOFWEEK(?))
                       )";
        $closureStmt = $pdo->prepare($closureQuery);
        $closureStmt->execute([$date, $date, $date]);
        $closure = $closureStmt->fetch(PDO::FETCH_ASSOC);
        
        if ($closure) {
            error('该日期临时闭馆: ' . ($closure['reason'] ?: '临时闭馆'));
        }
        
        // 获取时间段信息
        $timeSlotsQuery = "SELECT * FROM museum_time_slots WHERE is_active = 1 ORDER BY sort_order, start_time";
        $timeSlots = $pdo->query($timeSlotsQuery)->fetchAll(PDO::FETCH_ASSOC);
        
        $availableSlots = [];
        foreach ($timeSlots as $slot) {
            // 检查时间段是否在开馆时间内
            if ($slot['start_time'] >= $schedule['open_time'] && $slot['end_time'] <= $schedule['close_time']) {
                // 查询预约情况
                $reservedQuery = "SELECT COALESCE(SUM(visitor_count), 0) as reserved_count 
                                FROM reservations 
                                WHERE visit_date = ? AND time_slot_id = ? 
                                AND status IN ('confirmed', 'checked_in')";
                $reservedStmt = $pdo->prepare($reservedQuery);
                $reservedStmt->execute([$date, $slot['id']]);
                $reservedData = $reservedStmt->fetch(PDO::FETCH_ASSOC);
                
                $maxVisitors = (int)$slot['max_visitors'];
                $reservedCount = (int)($reservedData['reserved_count'] ?? 0);
                $availableCount = max(0, $maxVisitors - $reservedCount);
                
                $availableSlots[] = [
                    'slot_id' => (int)$slot['id'],
                    'slot_name' => $slot['slot_name'],
                    'start_time' => substr($slot['start_time'], 0, 5),
                    'end_time' => substr($slot['end_time'], 0, 5),
                    'max_visitors' => $maxVisitors,
                    'reserved_count' => $reservedCount,
                    'available_count' => $availableCount,
                    'is_available' => $availableCount > 0
                ];
            }
        }
        
        success([
            'date' => $date,
            'day_name' => ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日'][date('N', strtotime($date))],
            'open_time' => substr($schedule['open_time'], 0, 5),
            'close_time' => substr($schedule['close_time'], 0, 5),
            'max_visitors' => (int)$schedule['max_visitors'],
            'available_slots' => $availableSlots
        ]);
        
    } catch (Exception $e) {
        error('获取日期详情失败: ' . $e->getMessage(), 500);
    }
}

// 处理请求
$action = $_GET['action'] ?? '';

try {
    switch ($action) {
        case '7days':
        case 'week':
            get7DaysSchedule();
            break;
        case 'date':
        case 'detail':
            getDateDetail();
            break;
        default:
            error('无效的操作，支持的操作: 7days (获取7日时间表), date (获取指定日期详情)');
    }
} catch (Exception $e) {
    error('服务器错误: ' . $e->getMessage(), 500);
}
?>